﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using PMS.Core.Caching;
using PMS.Core.Configuration.CommonEnumConfigs;
using PMS.Core.Utils;
using PMS.Services.Caching;
using PMS.Services.EntityServices;
using PMS.Services.EntityServices.Medias;
using PMS.Services.EntityServices.Stores;
using PMS.Services.Utils.Captcha;
using PMS.Web.Framework.Controllers;
using PMS.Web.Framework.Mvc.Filters;
using PMS.Web.Models.Medias;
using PMS.Web.Models.Stores;
using System;
using System.IO;
using System.Linq;

namespace PMS.Web.Controllers.WebApi.Common
{
    internal class zyUploadResponse
    {
        public int Id { get; set; }
        public string VirtualPath { get; set; }
    }
    /// <summary>
    /// 通用Webapi调用
    /// </summary>
    public class CommonWebApi : BaseApiController
    {
        #region Fields
        private readonly IStoreService _storeService;
        private readonly ICaptchaService _captchaService;
        private readonly IStaticCacheManager _cacheManager;
        private readonly ICacheKeyService _cacheKeyService;
        private readonly IMediaProvider _mediaServiceProvider;
        #endregion

        #region Ctor
        public CommonWebApi(IStoreService storeService,
            ICaptchaService captchaService,
            ICacheKeyService cacheKeyService,
            IStaticCacheManager cacheManager,
            IMediaProvider mediaServiceProvider)
        {
            _storeService = storeService;
            _captchaService = captchaService;
            _cacheManager = cacheManager;
            _cacheKeyService = cacheKeyService;
            _mediaServiceProvider = mediaServiceProvider;
        }
        #endregion

        #region Methods

        #region Captcha
        [HttpGet(WebApiRouteConfig.IsCaptchaEnabled)]
        public IActionResult IsCaptchaEnabled()
        {
            return SuccessJson("", _captchaService.IsCaptchaEnabled);
        }
        /// <summary>
        /// 获取图形验证码
        /// </summary>
        /// <param name="imgwidth"></param>
        /// <param name="imgheight"></param>
        /// <returns></returns>
        [HttpGet(WebApiRouteConfig.GenericCaptchaCode)]
        public IActionResult GenericCaptchaCodeApi(int imgwidth = 85, int imgheight = 40)
        {
            try
            {
                var captchamodel = _captchaService.CreateCaptcha(imgwidth, imgheight);
                if (captchamodel == null)
                    throw new PMSException(ApiResponseMessages.CaptchaNotEnabled, SystemLogLevel.Error);

                return SuccessJson("", captchamodel);
            }
            catch (PMSException pex)
            {
                return pex.LogLevel switch
                {
                    SystemLogLevel.Warning => WarnJson(pex.Message),
                    _ => ErrorJson(pex.Message)
                };
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }
        #endregion

        #region Store_For_CommonUse
        /// <summary>
        /// 公用API调用获取所有店铺信息用于下拉选择框使用
        /// </summary>
        /// <returns></returns>
        [HttpGet(WebApiRouteConfig.GetStoreSelectList)]
        public IActionResult GetStoreSelectListApi()
        {
            try
            {
                var storeEntities = _storeService.GetAllStores();
                if(storeEntities?.Any() ?? false)
                {
                    var models = storeEntities.Select(entity => new StoreSelectModel()
                    {
                        Id = entity.Id,
                        Name = entity.Name,
                        Url = entity.Url,
                        Order = entity.DisplayOrder,
                        Selected = false,
                        Disabled = false
                    });
                    return SuccessJson("", models.ToList(), true);
                }

                throw new PMSException(string.Format(ApiResponseMessages.EntityNotFound, ""), SystemLogLevel.Warning);
            }
            catch (PMSException pex)
            {
                return pex.LogLevel switch
                {
                    SystemLogLevel.Warning => WarnJson(pex.Message),
                    _ => ErrorJson(pex.Message)
                };
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }
        #endregion

        #region MediaFileUpload - For zyUpload: multiple upload component
        [AuthorizeCustomer(CustomerAuthorizeType.Guests)]
        [HttpPost(WebApiRouteConfig.ZYUploadApiUpload)]
        public IActionResult MediaResourceUploadForzyUploadApi([FromForm] MediaUploadRequsetModel formData)
        {
            try
            {
                if ((formData?.File ?? null) == null) throw new PMSException(ApiResponseMessages.ArgumentCannotBeNull, SystemLogLevel.Error);
                var fileProvider = CommonHelper.DefaultFileProvider;
                var fileExtension = MimeTypesManager.Instance.GetFileOutputExtName(fileProvider.GetFileExtension(formData.File.FileName));
                if (string.IsNullOrEmpty(fileExtension))
                    throw new PMSException(ApiResponseMessages.MediaFileNotSupport);

                var fileEntity = formData.Id > 0
                    ? _mediaServiceProvider.MediaService.UpdateMediaFile(formData.Id, formData.File, formData.Useage, formData.Title, formData.Description, formData.ImageLink)
                    : _mediaServiceProvider.MediaService.InsertMediaFile(formData.File, formData.Useage, formData.Title, formData.Description, formData.ImageLink);
                var urlPath = _mediaServiceProvider.MediaService.GetMediaFileUrl(ref fileEntity);
                return SuccessJson("", new zyUploadResponse { Id = fileEntity.Id, VirtualPath = urlPath.FileUrl });
            }
            catch (PMSException pex)
            {
                return pex.LogLevel switch
                {
                    SystemLogLevel.Warning => WarnJson(pex.Message),
                    _ => ErrorJson(pex.Message)
                };
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }

        [AuthorizeCustomer(CustomerAuthorizeType.Guests)]
        [HttpGet(WebApiRouteConfig.MediaFileDelete)]
        public IActionResult MediaResourceDeleteApi(int mediaFileId)
        {
            try
            {
                if (mediaFileId <= 0) 
                    throw new PMSException(ApiResponseMessages.MediaFileIdErrorForDelete, SystemLogLevel.Error);
                var fileProvider = CommonHelper.DefaultFileProvider;

                var delFile = _mediaServiceProvider.MediaService.GetMediaFileById(mediaFileId);
                if (delFile == null)
                    throw new PMSException(string.Format(ApiResponseMessages.EntityNotFound, "MediaFile"), SystemLogLevel.Error);
                bool deleted = _mediaServiceProvider.MediaService.DeleteMediaFile(delFile);
                
                return SuccessJson("", new { Success = deleted });
            }
            catch (PMSException pex)
            {
                return pex.LogLevel switch
                {
                    SystemLogLevel.Warning => WarnJson(pex.Message),
                    _ => ErrorJson(pex.Message)
                };
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }
        #endregion

        #region AreaSelect_For_CommonUse
        /// <summary>
        /// 获取省市县json数据
        /// </summary>
        /// <returns></returns>
        [AuthorizeCustomer(CustomerAuthorizeType.Guests)]
        [HttpGet(WebApiRouteConfig.GetAreaDataJson)]
        public IActionResult GetAreaDataApi()
        {
            try
            {
                var key = _cacheKeyService.PrepareKeyForDefaultCache(CacheKeyConfigs.AreaJsonDataAllCacheKey);
                var areaJson = _cacheManager.Get(key, () =>
                {
                    var fileProvider = CommonHelper.DefaultFileProvider;
                    var gzipfilePath = fileProvider.MapPath(CacheKeyConfigs.AreaGzipDataFilePath);
                    if (fileProvider.FileExists(gzipfilePath))
                    {
                        var serializer = new JsonSerializer();
                        using (var sr = new StreamReader(CommonHelper.DecompressFromFileAsync(gzipfilePath).Result))
                        using (var jsonTextReader = new JsonTextReader(sr))
                        {
                            return serializer.Deserialize(jsonTextReader);
                        }
                    }
                    return null;
                });
                return SuccessJson("", areaJson);
            } 
            catch(Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }
        #endregion

        #endregion
    }
}
